package xyz.wanwanwan.www.hrm.service.impl;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import xyz.wanwanwan.www.hrm.domain.CourseType;
import xyz.wanwanwan.www.hrm.feign.client.CacheFeign;
import xyz.wanwanwan.www.hrm.mapper.CourseTypeMapper;
import xyz.wanwanwan.www.hrm.service.ICourseTypeService;
import xyz.wanwanwan.www.hrm.util.AjaxResult;
import xyz.wanwanwan.www.hrm.constants.RedisContans;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import xyz.wanwanwan.www.hrm.vo.CourseVo;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * <p>
 * 课程目录 服务实现类
 * </p>
 *
 * @author Mr.Fu
 * @since 2020-09-11
 */
@Service
@Slf4j
@Transactional
public class CourseTypeServiceImpl extends ServiceImpl<CourseTypeMapper, CourseType> implements ICourseTypeService {
    @Autowired
    private CacheFeign cacheFeign;
    /**
     * 课程类型分级菜单查询
     * @return
     */
    @Override
    public List<CourseType> treeData() {
        //1.查询出所有课程类型
        List<CourseType> courseTypes = SelectCourseTypeFromCacheOrDB();
        return getCourseTypesTree(courseTypes);
    }

    /**
     * 课程类型面包屑
     * //1.查询出请求课程类型
       //2.查询出课程类型path
       //3.遍历path获取课程类型数组
       //4.查询出个课程类型数组同等级课程类型
       //5.将数据封装到CourseVo中返回
     * @param productTypeId
     * @return
     */
    @Override
    public List<CourseVo> crumbs(Long productTypeId) {
        //1.查询出请求课程类型
        CourseType courseType = baseMapper.selectById(productTypeId);
        //2.查询出课程类型path
        String path = courseType.getPath();
        String[] courseTypesId = path.split("\\.");
        //3.遍历path获取课程类型数组
        List<CourseType> courseTypes = baseMapper.selectBatchIds(Arrays.asList(courseTypesId));
        ArrayList<CourseVo> CourseVos = new ArrayList<>();
        courseTypes.forEach(c->{
            //4.查询出个课程类型数组同等级课程类型
            List<CourseType> othersCourseType = baseMapper.selectByPid(c.getPid());
            //5.将数据封装到CourseVo中返回
            CourseVo courseVo = new CourseVo(c, othersCourseType);
            CourseVos.add(courseVo);
        });
        return CourseVos;
    }

    /**
     * 查询课程类型
     * @return
     */
    private List<CourseType> SelectCourseTypeFromCacheOrDB(){
        //从redis获取缓冲
        AjaxResult fromRedis = cacheFeign.getFromRedis(RedisContans.KEY_COURSETYPE_ALL);
        //判断缓冲中是否有查询数据
        if(fromRedis.isSuccess()&&fromRedis.getResultObj()!=null){
            //如果有数据则直接查询并返回
            String jsonString = fromRedis.getResultObj().toString();
            //将字符串转换为json格式的集合
            List<CourseType> courseTypes = JSON.parseArray(jsonString, CourseType.class);
            return courseTypes;
        }else{
            //如果缓冲中没有查询数据，则从数据库查询,并存储到redis中
            List<CourseType> courseTypes = baseMapper.selectList(null);
            //将数据转换为json字符串存入redis
            String jsonCourseTypes = JSON.toJSONString(courseTypes);
            AjaxResult ajaxResult = cacheFeign.setToRedis(RedisContans.KEY_COURSETYPE_ALL, jsonCourseTypes);
            if(!ajaxResult.isSuccess()){
                log.error("缓存课程类型失败！！！！！");
            }
            return courseTypes;
        }
    }

    /**
     * 分级课程类型
     * @param courseTypes
     * @return
     */
    private List<CourseType> getCourseTypesTree(List<CourseType> courseTypes) {
        //2.遍历类型，查询出所有一级课程类型
        List<CourseType> firstStepCourseType = new ArrayList<>();
        for (CourseType courseType : courseTypes) {
            //如果为一级课程类型
            if(courseType.getPid()==0){
                firstStepCourseType.add(courseType);
            }else{
                //如果是非一级课程类型直接添加到到父类型中
                for (CourseType type : courseTypes) {
                    if(courseType.getPid().equals(type.getId())){
                        type.getChildren().add(courseType);
                        break;
                    }
                }
            }
        }
        return firstStepCourseType;
    }

    /**
     * 增加
     * @param entity
     * @return
     */
    @Override
    public boolean insert(CourseType entity) {
        boolean insert = super.insert(entity);
        //如果增加成功则删除redis
        if(insert){
            cacheFeign.delRedis(RedisContans.KEY_COURSETYPE_ALL);
        }
        return insert;
    }

    /**
     * 修改
     * @param entity
     * @return
     */
    @Override
    public boolean updateById(CourseType entity) {
        boolean update = super.updateById(entity);
        //如果修改成功则删除redis
        if(update){
            cacheFeign.delRedis(RedisContans.KEY_COURSETYPE_ALL);
        }
        return update;
    }

    /**
     * 删除
     * @param id
     * @return
     */
    @Override
    public boolean deleteById(Serializable id) {
        boolean delete = super.deleteById(id);
        //如果删除成功则删除redis
        if(delete){
            cacheFeign.delRedis(RedisContans.KEY_COURSETYPE_ALL);
        }
        return delete;
    }
}
